package com.tskj.leonsu.websocket;

import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;

import javax.websocket.EncodeException;
import javax.websocket.Session;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @notes:
 * @program: easystar2018_ss_v2.0
 * @author: JRX
 * @create: 2019-12-02 14:01
 **/
@Component
public class EasyStarProcess {

    private static CopyOnWriteArraySet<ProcessInfo> processList = new CopyOnWriteArraySet<>();

    public int size() {
        return processList.size();
    }

    public EasyStarProcess() {

    }

    public void add(String token, Session session) {
        ProcessInfo info = new ProcessInfo(token, session);
        processList.add(info);
    }

    public void update(String token, Session session) {
        Iterator<ProcessInfo> iterator = processList.iterator();
        while (iterator.hasNext()) {
            ProcessInfo info = iterator.next();
            if (info.getToken().equals(token)) {
                info.setSession(session);
                return;
            }
        }
    }
    public void remove(String token) {
        Iterator<ProcessInfo> iterator = processList.iterator();
        while (iterator.hasNext()) {
            ProcessInfo info = iterator.next();
            if (info.getToken().equals(token)) {
                processList.remove(info);
                return;
            }
        }
    }

    public void remove(Session session) {
        Iterator<ProcessInfo> iterator = processList.iterator();
        while (iterator.hasNext()) {
            ProcessInfo info = iterator.next();
            if (info.getSession().equals(session)) {
                processList.remove(info);
                return;
            }
        }
    }

    public Session getSession(String token) {
        Iterator<ProcessInfo> iterator = processList.iterator();
        while (iterator.hasNext()) {
            ProcessInfo info = iterator.next();
            if (info.getToken().equals(token)) {
                return info.getSession();
            }
        }
        return null;
    }

    public boolean exists(String token) {
        Iterator<ProcessInfo> iterator = processList.iterator();
        while (iterator.hasNext()) {
            ProcessInfo info = iterator.next();
            if (info.getToken().equals(token)) {
                return true;
            }
        }
        return false;
    }

    public boolean exists(Session session) {
        Iterator<ProcessInfo> iterator = processList.iterator();
        while (iterator.hasNext()) {
            ProcessInfo info = iterator.next();
            if (info.getSession().equals(session)) {
                return true;
            }
        }
        return false;
    }

    public String getToken(Session session) {
        Iterator<ProcessInfo> iterator = processList.iterator();
        while (iterator.hasNext()) {
            ProcessInfo info = iterator.next();
            if (info.getSession().equals(session)) {
                return info.getToken();
            }
        }
        return "";
    }

    public void sendText(String token, String msg) throws IOException {
        Session info = getSession(token);
        try {
            info.getBasicRemote().sendText(msg);
        } catch (IOException e) {
            remove(token);
            e.printStackTrace();
            throw e;
        }
    }

    public void sendMessage(String token, String msg) throws IOException {
        sendText(token, msg);
    }

    public void sendMessage(String token, JSONObject json) throws IOException {
        sendText(token, json.toJSONString());
    }

    /**
     * @param token
     * @param obj
     * @throws EncodeException 编码出错时，不会自动把此连接从连接库中移除
     * @throws IOException     IO出错时，说明客户端已经断开连接，需要把此连接从连接库中移除
     */
    public void sendObject(String token, Object obj) throws EncodeException, IOException {
        Session info = getSession(token);
        try {
            info.getBasicRemote().sendObject(obj);
        } catch (EncodeException e) {
            e.printStackTrace();
            throw e;
        } catch (IOException e) {
            remove(token);
            e.printStackTrace();
            throw e;
        }
    }

    public OutputStream getOutputStream(String token) throws IOException {
        Session info = getSession(token);
        if (info == null) {
            return null;
        }
        try {
            return info.getBasicRemote().getSendStream();
        } catch (IOException e) {
            remove(token);
            e.printStackTrace();
            throw e;
        }
    }

    public Writer getOutputWriter(String token) throws IOException {
        Session info = getSession(token);
        if (info == null) {
            return null;
        }
        try {
            return info.getBasicRemote().getSendWriter();
        } catch (IOException e) {
            remove(token);
            e.printStackTrace();
            throw e;
        }
    }

    public void sendText(Session session, String message) throws IOException {
        session.getBasicRemote().sendText(message);
    }

    public void sendText(Session session, JSONObject message) throws IOException {
        sendText(session, message.toJSONString());
    }

    public void sendToAll(JSONObject obj) {
        Iterator<ProcessInfo> iterator = processList.iterator();
        while (iterator.hasNext()) {
            ProcessInfo info = iterator.next();
            try {
                info.getSession().getBasicRemote().sendText(obj.toString());
            } catch (IOException e) {
                e.printStackTrace();
                processList.remove(info);
            }
        }
    }
    class ProcessInfo {
        /**
         * 用户ID，暂时没用
         */
        private String userId = "";

        /**
         * websocket人session
         */
        private Session session = null;

        /**
         * 主机的cookie的sessionId
         */
        private String jSessionId = "";

        private String token = "";
        /**
         * 当前的档案ID
         */
        private String docId = "";

        public ProcessInfo() {

        }

        public ProcessInfo(String token, Session session) {
            this.token = token;
            this.session = session;
        }

        public String getUserId() {
            return userId;
        }

        public void setUserId(String userId) {
            this.userId = userId;
        }

        public Session getSession() {
            return session;
        }

        public void setSession(Session session) {
            this.session = session;
        }

        public String getjSessionId() {
            return jSessionId;
        }

        public void setjSessionId(String jSessionId) {
            this.jSessionId = jSessionId;
        }

        public String getToken() {
            return token;
        }

        public void setToken(String token) {
            this.token = token;
        }

    }
}
